package com.hmall.order.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmall.common.client.ItemClient;
import com.hmall.common.client.UserClient;
import com.hmall.common.dto.Address;
import com.hmall.common.dto.ItemDTO;
import com.hmall.order.mapper.OrderMapper;
import com.hmall.order.pojo.Order;
import com.hmall.order.pojo.OrderDetail;
import com.hmall.order.pojo.OrderLogistics;
import com.hmall.order.pojo.RequestParams;
import com.hmall.order.service.IOrderDetailService;
import com.hmall.order.service.IOrderLogisticsService;
import com.hmall.order.service.IOrderService;
import com.hmall.order.service.WXPayService;
import com.hmall.order.utils.PayUtil;
import com.hmall.order.utils.UserHolder;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Map;
import java.util.UUID;

@Service
public class OrderService extends ServiceImpl<OrderMapper, Order> implements IOrderService {

    @Autowired
    private ItemClient itemClient;

    @Autowired
    private UserClient userClient;

    @Autowired
    private IOrderDetailService orderDetailService;

    @Autowired
    private IOrderLogisticsService logisticsService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private WXPayService wxPayService;

    /**
     * 创建订单
     *
     * @param requestParams
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Order createOrder(RequestParams requestParams) {
        //生成订单号
        String outTradeNo = PayUtil.getId("01");
        //调用微信支付SDK，生成微信支付二维码连接
        Map<String, String> aNative = wxPayService.createNative(outTradeNo, String.valueOf(1), requestParams.getItemId().toString());
        if (!("SUCCESS".equals(aNative.get("return_code")) && "SUCCESS".equals(aNative.get("result_code")))){
            //吐过微信支付SDK生成订单失败，直接返回订单创建失败
            throw new RuntimeException("微信支付二维码生成异常");
        }
        /**
         * 1 创建订单
         */
        //获取用户id
        Long userId = UserHolder.getUser();
        //创建订单对象
        Order order = new Order();
        //设置订单对象参数
        order.setTradeNo(outTradeNo);//设置订单号
        order.setWxCodeUrl(aNative.get("code_url")); //设置微信支付订单二维码
        order.setUserId(userId);
        order.setPaymentType(requestParams.getPaymentType());
        order.setStatus(1);
        //通过商品id，获取商品信息
        ItemDTO itemDTO = itemClient.queryItemById(requestParams.getItemId().toString());
        if (itemDTO == null) {
            throw new RuntimeException("商品信息有误！");
        }
        order.setTotalFee(requestParams.getNum() * itemDTO.getPrice());

        boolean save = this.save(order);
        System.out.println("添加订单成功！结果为：" + save);

        /**
         * 创建订单详情
         *
         */
        //创建订单详情对象
        OrderDetail orderDetail = new OrderDetail();
        orderDetail.setOrderId(order.getId());
        orderDetail.setItemId(itemDTO.getId());
        orderDetail.setNum(requestParams.getNum());
        orderDetail.setName(itemDTO.getName());
        orderDetail.setSpec(itemDTO.getSpec());
        orderDetail.setPrice(itemDTO.getPrice());
        orderDetail.setImage(itemDTO.getImage());
        //将封装好的订单详情对象添加到数据库
        boolean save1 = orderDetailService.save(orderDetail);
        System.out.println("订单详情添加成功！结果为：" + save1);

        /**
         * 添加物流表
         */
        //根据addressId来获取地址信息
        Address address = userClient.findAddressById(requestParams.getAddressId());
        if (address == null) {
            throw new RuntimeException("地址信息有误！");
        }
        OrderLogistics orderLogistics = new OrderLogistics();
        //将地址信息拷贝到OrderLogistics中
        BeanUtils.copyProperties(address,orderLogistics);
        //设置参数
        orderLogistics.setOrderId(orderDetail.getOrderId());
        orderLogistics.setLogisticsNumber("1231545664465");
        orderLogistics.setLogisticsCompany("顺丰快递");
        //保存到物流表
        boolean save2 = logisticsService.save(orderLogistics);
        System.out.println("物流信息保存结果：" + save2);

        /**
         * 扣减库存----这个参考别人代码写出来的
         */
        try {
            itemClient.updateStock(requestParams.getItemId(),-requestParams.getNum());
        } catch (Exception e) {
            throw new RuntimeException("库存不足！");
        }
        //延迟消息
        //1 30分钟后处理订单，如果没有支付就取消订单
        Message message = MessageBuilder
                .withBody(order.getId().toString().getBytes(StandardCharsets.UTF_8))
                .setDeliveryMode(MessageDeliveryMode.PERSISTENT)
                .setHeader("x-delay",1000 * 60 * 30)
                .build();
        //2 准备CorrelationData
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        rabbitTemplate.send("hmall.delay.direct","delay",message,correlationData);

        return order;
//        0.微信支付生成
//        暂时固定01业务号

//        String outTradeNo = PayUtil.getId("01");  //生成订单号
//
//        //调用微信支付SDK,生成微信支付二维码连接
//        Map<String, String> aNative = wxPayService.createNative(outTradeNo,String.valueOf(1),
//                requestParams.getItemId().toString());
//        if (!("SUCCESS".equals(aNative.get("return_code")) && "SUCCESS".equals(aNative.get("result_code")))) {
//            //如果微信支付SDK 生成订单失败, 直接返回订单创建失败
//            throw new RuntimeException("微信支付二维码生成异常");
//        }
//
//        Order order = new Order();
//        order.setTradeNo(outTradeNo);
//        order.setWxCodeUrl(aNative.get("code_url"));
//
//        // 1.查询商品
//        ItemDTO item = itemClient.queryItemById(requestParams.getItemId().toString());
//        // 2.基于商品价格、购买数量计算商品总价：totalFee
//        long totalFee = item.getPrice() * requestParams.getNum();
//        order.setTotalFee(totalFee);
//        order.setPaymentType(requestParams.getPaymentType());
//        order.setUserId(UserHolder.getUser());
//        order.setStatus(1);
//        // 3.将Order写入数据库tb_order表中
//        this.save(order);
//
//        // 4.将商品信息、orderId信息封装为OrderDetail对象，写入tb_order_detail表
//        OrderDetail detail = new OrderDetail();
//        detail.setName(item.getName());
//        detail.setSpec(item.getSpec());
//        detail.setPrice(item.getPrice());
//        detail.setNum(requestParams.getNum());
//        detail.setItemId(item.getId());
//        detail.setImage(item.getImage());
//        detail.setOrderId(order.getId());
//        orderDetailService.save(detail);
//
//
//        Long addressId = requestParams.getAddressId();
//        // 5.根据addressId查询user-service服务，获取地址信息
//        Address address = userClient.findAddressById(addressId);
//        // 6.将地址封装为OrderLogistics对象，写入tb_order_logistics表
//        OrderLogistics orderLogistics = new OrderLogistics();
//        BeanUtils.copyProperties(address, orderLogistics);
//        orderLogistics.setOrderId(order.getId());
//        logisticsService.save(orderLogistics);
//
//        // 7.扣减库存
//        try {
//            itemClient.updateStock(requestParams.getItemId(), -requestParams.getNum());
//        } catch (Exception e) {
//            throw new RuntimeException("库存不足！");
//        }
//
//        // 1.延迟消息，30分钟之后处理订单，如果没有支付就取消订单
//        Message message = MessageBuilder
//                .withBody(order.getId().toString().getBytes(StandardCharsets.UTF_8))
//                .setDeliveryMode(MessageDeliveryMode.PERSISTENT)
//                .setHeader("x-delay", 1000 * 60 *30)
//                .build();
//        // 2.准备CorrelationData
//        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
//
//        rabbitTemplate.send("hmall.delay.direct","delay",message,correlationData);
//
//        return order;
    }

    /**
     * 处理过期订单业务
     * @param orderId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void dealExpireOrder(long orderId) {
        Order order = this.getById(orderId);
        if(order == null){
            throw new RuntimeException("订单不存在！");
        }

        if(!order.getStatus().equals(1)){
            throw new RuntimeException("订单状态不正确！");
        }

        OrderDetail detail = orderDetailService.getOne(Wrappers.<OrderDetail>lambdaQuery().eq(OrderDetail::getOrderId, orderId));
        Integer num = detail.getNum();
        Long itemId = detail.getItemId();

        itemClient.updateStock(itemId, num);

        order.setCloseTime(new Date());
        order.setStatus(5);
        updateById(order);

        //关闭微信订单
        wxPayService.closeNative(order.getTradeNo());

    }
}
